﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using VaccineEbook.Models;
using VaccineEbook.Models.DBEntity;
using VaccineEbook.Common;
using System.Data.Entity.Validation;
using System.Diagnostics;

namespace VaccineEbook.Controllers
{
    public class MobileUserController : ApiController
    {
        
        VaccineEBookEntities _db = new VaccineEBookEntities();
        // GET api/mobileuser

        #region [View]
        [HttpGet]
        [ActionName("GetAll")]
        public IEnumerable<User> GetAll()
        {
            try
            {
                var _user = (from u in _db.Users select u);
                IEnumerable<User> user = _user.ToList().AsQueryable();
                if (user != null)
                {
                    return user;
                }
                else
                    return null;
            }
            catch
            {
                return null;
            }
        }

        [HttpGet]
        [ActionName("GetAllUser")]
        public HttpResponseMessage GetAllUser()
        {
            try
            {
                var _user = (from u in _db.Users select u);
                IEnumerable<User> user = _user.ToList().AsQueryable();
                if (user != null)
                {
                    return Request.CreateResponse<IEnumerable<User>>(HttpStatusCode.OK, user);
                }
                else
                    return Request.CreateResponse(HttpStatusCode.NotFound);
            }
            catch
            {
                return Request.CreateResponse(HttpStatusCode.BadGateway);
            }

        }

        // GET api/user/5        
        public HttpResponseMessage GetUser(int id)
        {

            if (string.IsNullOrEmpty(id.ToString()))
            {
                return Request.CreateErrorResponse(HttpStatusCode.NoContent, MESSAGE_STRING.EMPTY_DATA);


            }
            try
            {
                //User user = _db.Users.Where(u => u.UserID == id).Single();
                //if (user != null)
                //{
                //    return Request.CreateResponse<IEnumerable<User>>(HttpStatusCode.OK, user);
                //}
                //else
                //{
                return Request.CreateResponse(HttpStatusCode.NotFound);
                //}

            }
            catch
            {
                return Request.CreateResponse(HttpStatusCode.BadGateway);
            }
        }


        [HttpGet]
        [ActionName("GetAllVaccine")]
        public HttpResponseMessage GetAllVaccine()
        {
            try
            {
                var _vaccine = (from u in _db.Vaccines select u);
                IEnumerable<Vaccine> vaccine = _vaccine.ToList().AsQueryable();
                if (vaccine != null)
                {
                    return Request.CreateResponse<IEnumerable<Vaccine>>(HttpStatusCode.OK, vaccine);
                }
                else
                    return Request.CreateResponse(HttpStatusCode.NotFound);
            }
            catch
            {
                return Request.CreateResponse(HttpStatusCode.BadGateway);
            }

        }

        [HttpGet]
        [ActionName("GetAllVaccineRecord")]
        public HttpResponseMessage GetAllVaccineRecord(int userID)
        {
            if (string.IsNullOrEmpty(userID.ToString()))
                return Request.CreateErrorResponse(HttpStatusCode.NotModified, MESSAGE_STRING.EMPTY_DATA);
            MobileModel.Result mode = new MobileModel.Result();
            try
            {
                var _vaccineRecord = (from v in _db.VaccineRecords where v.UserID == userID select v);
                IEnumerable<VaccineRecord> vaccineRecord = _vaccineRecord.ToList().AsQueryable();
                if (vaccineRecord != null)
                {
                    mode.Status = HttpStatusCode.Accepted.ToString();
                    mode.Id = userID.ToString();
                    mode.Message = MESSAGE_STRING.GET_DATA_SUCCESSFUL;
                    return Request.CreateResponse<IEnumerable<VaccineRecord>>(HttpStatusCode.OK, vaccineRecord);
                }
                else
                {
                    mode.Status = HttpStatusCode.NotFound.ToString();
                    mode.Id = userID.ToString();
                    mode.Message = MESSAGE_STRING.EMPTY_DATA;
                    return Request.CreateResponse(HttpStatusCode.NotFound);
                }
            }
            catch
            {
                mode.Status = HttpStatusCode.BadGateway.ToString();
                mode.Message = MESSAGE_STRING.CONNECTION_FAIL;
                return Request.CreateResponse(HttpStatusCode.BadGateway);
            }

        }

        [HttpGet]
        [ActionName("GetVaccineRecord")]
        public HttpResponseMessage GetVaccineRecord(int vaccineRecordID)
        {
            if(string.IsNullOrEmpty(vaccineRecordID.ToString()))
                return Request.CreateErrorResponse(HttpStatusCode.NotModified, MESSAGE_STRING.EMPTY_DATA);
            MobileModel.Result mode = new MobileModel.Result();
            try
            {
                VaccineRecord vaccineRecord = _db.VaccineRecords.Where(v => v.VaccineRecordID == vaccineRecordID).Single();
                if (vaccineRecord != null)
                {
                    mode.Status = HttpStatusCode.Accepted.ToString();
                    mode.Id = vaccineRecord.VaccineRecordID.ToString();
                    mode.Message = MESSAGE_STRING.GET_DATA_SUCCESSFUL;
                    return Request.CreateResponse(HttpStatusCode.OK, vaccineRecord);
                }
                else
                {
                    mode.Status = HttpStatusCode.NotFound.ToString();
                    mode.Id = vaccineRecord.VaccineRecordID.ToString();
                    mode.Message = MESSAGE_STRING.EMPTY_DATA;
                    return Request.CreateResponse(HttpStatusCode.NotFound);
                }
            }
            catch(Exception ex)
            {
                mode.Status = HttpStatusCode.BadGateway.ToString();                
                mode.Message = MESSAGE_STRING.CONNECTION_FAIL;
                return Request.CreateResponse(HttpStatusCode.BadGateway);
            }

        }


        #endregion

        #region [Login/Register]

        // POST api/user
        public void Post([FromBody]string value)
        {
        }

        [HttpPost]
        public HttpResponseMessage Login([FromBody] MobileModel.Login login)
        {
            MobileModel.Result mode = new MobileModel.Result();
            try
            {
                if (string.IsNullOrEmpty(login.Password))
                    return Request.CreateErrorResponse(HttpStatusCode.NotModified, MESSAGE_AUTH_STRING.EMPTY_PASSWORD);
                if (string.IsNullOrEmpty(login.UserName))
                    return Request.CreateErrorResponse(HttpStatusCode.NotModified, MESSAGE_AUTH_STRING.EMPTY_USERNAME);                
                string encodePassword = EncryptionUtil.Encode(login.Password, login.UserName.Trim().ToLower());
                User user = _db.Users.Where(u => u.Username == login.UserName).Single();
                if (user != null)
                {
                    if (user.UserStatus != (int)STATUS_USER.MOBILE_ACTIVE)
                        return Request.CreateResponse(HttpStatusCode.Unused);
                    if (user.Password != encodePassword)
                        return Request.CreateResponse(HttpStatusCode.Unauthorized);
                    mode.Status = HttpStatusCode.Accepted.ToString();
                    mode.Id = user.UserID.ToString();
                    mode.Message = MESSAGE_STRING.LOGIN_SUCCESSFUL;
                    return Request.CreateResponse<MobileModel.Result>(HttpStatusCode.Accepted, mode);
                }
                else
                {
                    mode.Status = HttpStatusCode.NotFound.ToString();
                    mode.Id = user.UserID.ToString();
                    mode.Message = MESSAGE_STRING.EMPTY_DATA;
                    return Request.CreateResponse(HttpStatusCode.NotFound);
                }
            }
            catch
            {
                mode.Status = HttpStatusCode.BadGateway.ToString();
                mode.Message = MESSAGE_STRING.EMPTY_DATA;
                return Request.CreateResponse(HttpStatusCode.NotFound);                
            }

        }

        [HttpPost]
        public HttpResponseMessage Register([FromBody] MobileModel.Register user)
        {
            MobileModel.Result mode = new MobileModel.Result();
            try
            {
                if (string.IsNullOrEmpty(user.Password))
                    return Request.CreateErrorResponse(HttpStatusCode.NotModified,MESSAGE_AUTH_STRING.EMPTY_PASSWORD);
                if (string.IsNullOrEmpty(user.UserName))
                    return Request.CreateErrorResponse(HttpStatusCode.NotModified, MESSAGE_AUTH_STRING.EMPTY_USERNAME);
                if(string.IsNullOrEmpty(user.ConfirmPassword) || string.Compare(user.Password,user.ConfirmPassword) != 0)
                    return Request.CreateErrorResponse(HttpStatusCode.NotModified, MESSAGE_AUTH_STRING.EMPTY_CONFIRM_PASSWORD);
                
                int existed = CheckData.CheckUser(user.UserName) ;
                if ( existed == 0)
                {
                    mode.Status = HttpStatusCode.Found.ToString();
                    mode.Message = MESSAGE_STRING.USERNAME_EXISTS.ToString();
                    return Request.CreateResponse<MobileModel.Result>(HttpStatusCode.Found, mode);
                }
                else if (existed == -2)
                {
                    mode.Status = HttpStatusCode.BadGateway.ToString();
                    mode.Message = MESSAGE_STRING.CONNECTION_FAIL.ToString();
                    return Request.CreateResponse<MobileModel.Result>(HttpStatusCode.BadGateway, mode);
                }
                if (this.ModelState.IsValid && existed == -1)
                {
                    User _user = new User();
                    _user.Username = user.UserName;
                    _user.Password = EncryptionUtil.Encode(user.Password, user.UserName.Trim().ToLower());
                    _user.ConfirmPassword = EncryptionUtil.Encode(user.ConfirmPassword, user.UserName.Trim().ToLower());
                    _user.UserStatus = (int)STATUS_USER.MOBILE_ACTIVE;
                    _user.Status = (int)STATUS_OBJECT.ACTIVE;
                    _user.LastModifined = DateTime.UtcNow;
                    _db.Users.Add(_user);                    
                    _db.SaveChanges();
                    if (_user != null)
                    {
                        mode.Id = _user.UserID.ToString();
                        mode.Status = HttpStatusCode.Created.ToString();
                        mode.Message = MESSAGE_STRING.USER_CREATED;
                        var httpRespone = Request.CreateResponse<MobileModel.Result>(HttpStatusCode.Created, mode);
                        string uri = Url.Link("DefaultApi", new { id = mode.Id });
                        httpRespone.Headers.Location = new Uri(uri);
                        return httpRespone;

                    }
                    return Request.CreateResponse(HttpStatusCode.BadRequest);
                }
                else
                    return Request.CreateResponse(HttpStatusCode.NotAcceptable);

            }
            catch (DbEntityValidationException dbEx)
            {
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}", validationErrors.Entry.Entity.GetType().FullName,
                                      validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
                return Request.CreateResponse(HttpStatusCode.BadGateway);
            }
        }

        [HttpPost]
        public HttpResponseMessage CreateVaccineRecord([FromBody] MobileModel.CreateVaccineRecord vaccineRecord)
        {
            MobileModel.Result mode = new MobileModel.Result();
            try
            {                
                if (string.IsNullOrEmpty(vaccineRecord.Note))
                    return Request.CreateErrorResponse(HttpStatusCode.NotModified, MESSAGE_STRING.EMPTY_DATA);
                if (this.ModelState.IsValid)
                {
                    VaccineRecord _vaccineRecord = new VaccineRecord();
                    _vaccineRecord.VaccineName = vaccineRecord.VaccineName;
                    _vaccineRecord.DiseaseName = vaccineRecord.DiseaseName;
                    _vaccineRecord.HadDisease = vaccineRecord.HadDisease;
                    _vaccineRecord.Date = vaccineRecord.Date;
                    _vaccineRecord.Note = vaccineRecord.Note;
                    _vaccineRecord.UserID = vaccineRecord.UserID;
                    _vaccineRecord.LastModifined = DateTime.UtcNow;
                    _db.VaccineRecords.Add(_vaccineRecord);
                    _db.SaveChanges();
                    if (_vaccineRecord != null)
                    {
                        mode.Id = _vaccineRecord.VaccineRecordID.ToString();
                        mode.Status = HttpStatusCode.Created.ToString();
                        mode.Message = MESSAGE_STRING.VACCINERECORD_CREATED;
                        var httpRespone = Request.CreateResponse<MobileModel.Result>(HttpStatusCode.Created, mode);
                        string uri = Url.Link("DefaultApi", new { id = mode.Id });
                        httpRespone.Headers.Location = new Uri(uri);
                        return httpRespone;
                    }
                    return Request.CreateResponse(HttpStatusCode.BadRequest);
                }
                else
                {
                    foreach (var modelStateVal in ModelState.Values)
                    {
                        foreach (var error in modelStateVal.Errors)
                        {
                            var errorMessage = error.ErrorMessage;
                            var exception = error.Exception;
                            // You may log the errors if you want
                        }
                    }
                    return Request.CreateResponse(HttpStatusCode.NotAcceptable);
                }

            }
            catch (DbEntityValidationException dbEx)
            {
                foreach (var validationErrors in dbEx.EntityValidationErrors)
                {
                    foreach (var validationError in validationErrors.ValidationErrors)
                    {
                        Trace.TraceInformation("Class: {0}, Property: {1}, Error: {2}", validationErrors.Entry.Entity.GetType().FullName,
                                      validationError.PropertyName, validationError.ErrorMessage);
                    }
                }
                return Request.CreateResponse(HttpStatusCode.BadGateway);
            }
        }
       
        #endregion

        // PUT api/user/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/user/5
        public void Delete(int id)
        {
        }
    }
}
